﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DVK.SP2007;
using DVK.SP2007.UniversalClient;
using DVK.SP2007.UniversalClient.DataAccess;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint;
using System.Text;
using System.Net.Mime;
using Microsoft.SharePoint.Utilities;
using System.Web.Script.Serialization;
using System.Xml.Linq;
using DVK.SP2007.Constants;
using DVK.SP2007.Resources;

namespace DVK.SP2007.Pages
{
    /// <summary>
    /// DocumentHistory page shows the Documents DVK history.
    /// This includes:
    ///     All sendings with links to original messages.
    ///     Reciving, if the document was originally received from DVK.
    /// </summary>
    public partial class DocumentHistory : LayoutsPageBase
    {
        SPListItem _item;
        protected SPWeb _web;

        #region Events
        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            string itemUrl = Request.Params[Constants.Params.QueryStringParameterItemUrl];

            _web = SPContext.Current.Web;
            _item = _web.GetListItem(itemUrl);

            if (!this.IsPostBack)
            {
                lblDocName.Text = _item.Name;
                lblDocUrl.Text = itemUrl;

                SPList outboxList = _web.GetListFromUrl(Constants.Urls.ListOutbox);
                SPList inboxList = _web.GetListFromUrl(Constants.Urls.ListInbox);
                SPList archiveList = _web.GetListFromUrl(Constants.Urls.ListDvkMessageArchive);

                //Get sent items for history
                var sentItems = GetItems(outboxList);
                //Get received items for history
                var receivedItems = GetItems(inboxList);
                //Get sent and received items from Dvk History list
                var archivedItems = GetItems(archiveList);
                
                //need to use contenttype to distinct wether a item is sent or received
                SPContentType ctOutboxDocument = outboxList.ContentTypes[outboxList.ContentTypes.BestMatch(new SPContentTypeId(ContentTypes.OutboxDocument.ID))];
                SPContentType ctInboxDocument = inboxList.ContentTypes[inboxList.ContentTypes.BestMatch(new SPContentTypeId(ContentTypes.InboxDocument.ID))];

                //Merge based on contenttype into the sent or receiveditems list
                MergeItems(sentItems, archivedItems, ctOutboxDocument);
                MergeItems(receivedItems, archivedItems, ctInboxDocument);

                this.rptSentMessages.DataSource = sentItems;
                this.rptSentMessages.DataBind();

                this.rptReceivedMessages.DataSource = receivedItems;
                this.rptReceivedMessages.DataBind();
            }
        }

        /// <summary>
        /// Handles the Click event of the btnOK control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void btnOK_Click(object sender, EventArgs e)
        {
            SPUtility.Redirect(_item.ParentList.DefaultViewUrl, SPRedirectFlags.Default, Context);
        }

        #endregion

        /// <summary>
        /// Merges to lists listitems based on items contenttype.
        /// </summary>
        /// <param name="items">The items.</param>
        /// <param name="archivedItems">The archived items.</param>
        /// <param name="contentType">Type of the content.</param>
        private void MergeItems(List<SPListItem> items, List<SPListItem> archivedItems, SPContentType contentType)
        {
            foreach (SPListItem item in archivedItems)
            {
                if (item.ContentType.Name.Equals(contentType.Name))
                {
                    items.Add(item);
                }
            }
        }

        /// <summary>
        /// Queries items from SPList based on DocumentLibraryItemId.
        /// </summary>
        /// <param name="list">The list.</param>
        /// <returns></returns>
        private List<SPListItem> GetItems(SPList list)
        {
            List<SPListItem> resultItems = new List<SPListItem>();

            SPQuery query = new SPQuery();
            query.RowLimit = 100;
            query.ViewAttributes = "Scope=\"Recursive\"";
            query.Query = "<Where>" +
                          "<Eq><FieldRef Name='" + Fields.DocumentLibraryItemId.Name + "' /><Value Type='Integer'>" + _item.ID + "</Value></Eq>" +
                          "</Where>";
            SPListItemCollection items = list.GetItems(query);

            foreach (SPListItem item in items)
            {
                resultItems.Add(item);
            }

            return resultItems;
        }

        #region View helper methods

        /// <summary>
        /// Generates the link to show in the table and that navigates to the items display form.
        /// </summary>
        /// <param name="dataItem">The data item.</param>
        /// <returns></returns>
        public string GetItemLink(object dataItem)
        {
            SPListItem item = dataItem as SPListItem;
            string listName = item.Url.Split('/')[0];
            string url = _web.Url + "/" + listName + "/Forms/DispForm.aspx" + "?ID=" + item.ID;
            return url;
        }

        /// <summary>
        /// Gets fields metadata value.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="fieldName">Name of the field.</param>
        /// <returns></returns>
        public string GetMetadata(SPListItem item, string fieldName)
        {
            if (item == null)
                return string.Empty;

            string data = item[fieldName] as string;
            return string.IsNullOrEmpty(data) ? string.Empty : data;
        }

        /// <summary>
        /// Gets the metadata.
        /// </summary>
        /// <param name="dataItem">The data item.</param>
        /// <param name="fieldName">Name of the field.</param>
        /// <returns></returns>
        public string GetMetadata(object dataItem, string fieldName)
        {
            return GetMetadata(dataItem as SPListItem, fieldName);
        }

        /// <summary>
        /// Gets fields metadata value as DateTime string.
        /// </summary>
        /// <param name="dataItem">The data item.</param>
        /// <param name="fieldName">Name of the field.</param>
        /// <returns></returns>
        public string GetMetadataDate(object dataItem, string fieldName)
        {
            DateTime? data = (dataItem as SPListItem)[fieldName] as DateTime?;
            if (data.HasValue) return data.Value.ToShortDateString();
            return string.Empty;
        }

        /// <summary>
        /// Gets the sender info.
        /// </summary>
        /// <param name="dataItem">The data item.</param>
        /// <returns></returns>
        public string GetSenderInfo(object dataItem)
        {
            SPListItem item = dataItem as SPListItem;
            string organisationName = GetMetadata(item, Fields.SenderOrganisationName.Name);
            string personName = GetMetadata(item, Fields.SenderPersonName.Name);
            return organisationName + ", " + personName;
        }

        /// <summary>
        /// Gets the recipients info.
        /// </summary>
        /// <param name="dataItem">The data item.</param>
        /// <returns></returns>
        public string GetRecipientsInfo(object dataItem)
        {
            SPListItem item = dataItem as SPListItem;

            string metaXml = GetMetadata(item, Fields.DvkMetaXml.Name);
            StringBuilder recipientInfo = new StringBuilder(50);

            try
            {
                DvkMetaXmlPart metaXmlPart = new DvkMetaXmlPart(XElement.Parse(metaXml));
                var addressees = metaXmlPart.GetAddressees();

                foreach (var addressee in addressees)
                {
                    var firstName = addressee.Descendants(DvkMetaXmlPart.ElementNamePersonFirstname).Single();
                    var surName = addressee.Descendants(DvkMetaXmlPart.ElementNamePersonSurname).Single();
                    var organisationName = addressee.Descendants(DvkMetaXmlPart.ElementNameOrganisationName).Single();
                    recipientInfo.AppendFormat(
                        "{0}, {1} {2}; ",
                        organisationName.Value,
                        firstName.Value,
                        surName.Value);
                }
            }
            catch (Exception exc)
            {
                lbErrorMessage.Text = 
                    string.Format(DvkWeb.DocumentHistory_ErrorRecipientsInfoLoadFailed, exc.ToString());
            }
            return recipientInfo.ToString();
        }

        #endregion
    }
}
